package com.qfxl.common.comm;

/**
 * @Title: Token
 * @Author cj
 * @Package com.cj.common
 * @Date 2025/5/22 17:45
 * @description:
 */

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;

import java.nio.file.Paths;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author cj
 * @version 1.0
 * @description: TODO
 * @date 2025/5/22 17:45
 */
public class JwtToken {
    /**
     * 创建token
     *
     * @param userInfoJson         用户学习json格式
     * @param privateKey           私钥
     * @param expirationTimeSecond 过期时间:秒
     * @return token字符串
     */
    public static String createToken(String userInfoJson, PrivateKey privateKey, Long expirationTimeSecond) {
        try {
            /*
           JWT（JSON Web Token）是一种开放标准（由RFC 7519定义），用于在各方之间安全地传输信息作为JSON对象。
           它特别适用于在网络应用环境间安全地传递声明，比如用户身份验证和授权信息。
           JWT通常用于实现无状态的、服务器端会话管理，允许服务提供者在不存储任何关于用户的会话信息的情况下验证用户的身份。

           是一种开放标准、安全地在各方间传输信息、方便身份验证和授权
           组成：头部(header)、载荷(payload)、签名(signature)
           头部-声明类型，声明加密的算法
           {
             "alg": "HS256",
             "typ": "JWT"
            }
           载荷-用来存放实际需要传递的数据
           Payload 部分也是一个 JSON 对象，用来存放实际需要传递的数据。JWT 规定了7个官方字段，供选用。
             iss (issuer)：签发人
             exp (expiration time)：过期时间
             sub (subject)：主题
             aud (audience)：受众
             nbf (Not Before)：生效时间
             iat (Issued At)：签发时间
             jti (JWT ID)：编号
            除以上默认字段外，我们还可以自定义私有字段，如下例：
             {
             "sub": "1234567890",
             "name": "chongchong",
             "admin": true
             }
             签名-服务器通过 Payload、Header 和一个密钥(Secret)使用 Header 里面指定的签名算法（默认是 HMAC SHA256）生成。生成的签名会成为 JWT 的第三部分。
            * */
            // String token;
            Date date = new Date();
            // 令牌id
            String uuid = UUID.randomUUID().toString();
            String token = Jwts.builder()
                    .header()
                    .add("typ", "JWT")
                    .add("alg", "HS256")
                    .and()
                    .subject("token")
                    // 设置自定义负载信息payload
                    .claim("userInfo", userInfoJson)
                    // 令牌ID
                    .id(uuid)
                    // 签发时间
                    .issuedAt(new Date())
                    // 过期日期
                    .expiration(new Date(date.getTime() + (expirationTimeSecond * 1000)))
                    // 主题
                    .subject("token")
                    // 签名
                    .signWith(privateKey)
                    .compact();
            return token;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 解析token
     *
     * @param token     token
     * @param publicKey 公钥
     * @return token
     */
    public static Map<String, Object> analysisToken(String token, PublicKey publicKey,String payloadField) {
        //解析
        Jws<Claims> claimsJws = Jwts.parser()
                .verifyWith(publicKey)
                .build().parseSignedClaims(token);
        Claims payload = claimsJws.getPayload();
//        Date expiration = payload.getExpiration();
//        Instant instant = expiration.toInstant();
//        // 获取系统默认时区
//        ZoneId zoneId = ZoneId.systemDefault();
//        // 将Instant和ZoneId转换为LocalDateTime
//        LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
//        System.out.println(localDateTime);
        Map<String, Object> restMap = JSON.parseObject(String.valueOf(payload.get(payloadField)), new TypeReference<Map<String, Object>>() {
        });
        return restMap;
    }

    public static void main(String[] args) throws Exception {
        PublicKey publicKey = SecretKey.loadPublicKey(Paths.get("PublicKey.key"));
        PrivateKey privateKey = SecretKey.loadPrivateKey(Paths.get("PrivateKey.key"));
        Map<String, Object> userInfoMap = new HashMap<>();
        userInfoMap.put("userName", "证书");
        userInfoMap.put("userAge", 12);
        //JSON
        String json = JSON.toJSONString(userInfoMap);
        String token = createToken(json, privateKey, 3L);
        System.out.println("生成的Token:" + token);
        System.out.println("开始解析校验");
        String token1 = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ0b2tlbiIsInVzZXJJbmZvIjoie1widXNlck5hbWVcIjpcIuivgeS5plwiLFwidXNlckFnZVwiOjEyfSIsImp0aSI6ImJkODNkMWMzLWQwNzktNDJjZC05MTQ5LTBmZWUxZjc3NDQ5NSIsImlhdCI6MTc0Nzk4NTg2NSwiZXhwIjoxNzQ3OTg1ODY4fQ.HpIe5rQbPugjAJ8ft4bvSEzrNQBhpMSSwoppTFV1MqgKTup4-mMlkGD2sqAa5aHS_x6xqM7rfj9R26YIrdlkEfbFWgYU3zGGBG5dpseYK-CPgm_7N4a2RCGCOccTndbgAuHMtHu3xhXXt6d3-yQoN3s7WBTiNluHgu-7fTpEkZHXAaW7ofeW6waWpg2Z9ZPmnsGLm52ZoTLXMmyLfNp5CbC5FEY-gCyXZHUut-4javI8ke8aIgQjFUgpX5S-Y1FvHrSd1kBtvlVAr7OkWucJf7lo4KR2wbFHG6OKmtiM6dm2YVcsydV55iglfzxfNmcYAJ5Ap7GJ4Ox6kej3--Y1Rw";
        Map<String, Object> stringObjectMap = analysisToken(token1, publicKey,"userInfo");
        System.out.println(stringObjectMap);
    }


}
